
// <copyright file="LockFactory.cs" company="Subhadra Software Solutions">
//   
// </copyright>
// <summary>
//   The lock factory.
// </summary>

namespace SubhadraSolutions.Sharp.Utils.Diagnostics.Performance
{
    using SubhadraSolutions.Sharp.Utils.Collections.Concurrent;

    /// <summary>
    /// The lock factory.
    /// </summary>
    public class LockFactory : AbstractDisposable
    {
        #region Fields

        /// <summary>
        /// The lock.
        /// </summary>
        private readonly object syncLock = new object();

        /// <summary>
        /// The locks.
        /// </summary>
        private readonly CompositeDictionary<string, object> locks = new CompositeDictionary<string, object>(false);

        #endregion Fields

        #region Public Methods and Operators

        /// <summary>
        /// The get lock.
        /// </summary>
        /// <param name="machineName">
        /// The machine name.
        /// </param>
        /// <param name="processName">
        /// The process name.
        /// </param>
        /// <param name="environment">
        /// The environment.
        /// </param>
        /// <returns>
        /// The <see cref="object"/>.
        /// </returns>
        public object GetLock(string machineName, string processName, string environment)
        {
            lock (this.syncLock)
            {
                object o = this.locks.Get(machineName, processName, environment);
                if (o == null)
                {
                    o = new object();
                    this.locks.AddOrUpdate(o, machineName, processName, environment);
                }

                return o;
            }
        }

        #endregion Public Methods and Operators

        #region Methods

        /// <summary>
        /// The dispose.
        /// </summary>
        /// <param name="disposing">
        /// The disposing.
        /// </param>
        protected override void Dispose(bool disposing)
        {
            this.locks.Dispose();
        }

        #endregion Methods
    }
}